package org.iteam.xlz.manager.shiro;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.iteam.core.Constant;
import org.iteam.core.model.sys.SysUser;
import org.iteam.core.service.sys.SysUserService;

public class CustomAuthenticator extends AuthorizingRealm {

	/**
	 * 设置权限
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		if (principals == null) {
			throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
		}
		String username = (String) getAvailablePrincipal(principals);
		Set<String> roleNames = getRoleNamesForUser(username);
		Set<String> permissions = getPermissions(username, roleNames);
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
		info.setStringPermissions(permissions);
		return info;
	}

	/**
	 * 权限验证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken upToken = (UsernamePasswordToken) authcToken;
		String username = upToken.getUsername();
		AuthenticationInfo info = null;
		if (null != username && !"".equals(username)) {
			try {
				SysUser user = SysUserService.getInstance().show(username);
				if (null != user &&user.getStatus().equals(Constant.Status.ENABLE.getEcode())) {
					Subject subject = SecurityUtils.getSubject();
					subject.getSession().setAttribute(Constant.SESSION_CURRENT_USER, user);
					info = new SimpleAuthenticationInfo(username,user.getPassword(), getName());
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return info;
	}

	/**
	 * 获取用户角色
	 *
	 * @param username
	 * @return
	 */
	protected Set<String> getRoleNamesForUser(String username) {
		try {
			return null;
		} catch (Exception e) {
			e.printStackTrace();
			return new LinkedHashSet<String>();
		}
	}

	/**
	 * 获取用户角色权限
	 *
	 * @param username
	 * @param roleNames
	 * @return
	 */
	protected Set<String> getPermissions(String username, Collection<String> roleNames) {
		try {
			return null;
		} catch (Exception e) {
			e.printStackTrace();
			return new LinkedHashSet<String>();
		}
	}

	/**
	 * 更新用户授权信息缓存.
	 */
	public void clearCachedAuthorizationInfo(String principal) {
		SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
		clearCachedAuthorizationInfo(principals);
	}

	/**
	 * 清除所有用户授权信息缓存.
	 */
	public void clearAllCachedAuthorizationInfo() {
		Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
		if (cache != null) {
			for (Object key : cache.keys()) {
				cache.remove(key);
			}
		}
	}
}
